package com.huifanedu.approval.listener;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huifanedu.approval.constant.FlowableConstant;
import com.huifanedu.approval.entity.ApprovalFlowTaskcfg;
import com.huifanedu.approval.model.params.TaskParam;
import com.huifanedu.approval.service.ApprovalFlowTaskcfgService;
import com.huifanedu.approval.service.FlowableTaskService;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import java.util.List;
import java.util.Map;

/**
 * <b>功能名：TaskCompletedListener</b><br>
 * <b>说明：任务节点前置监听处理类</b><br>
 * <b>著作权：</b> Copyright (C) 2020 HUIFANEDU CORPORATION<br>
 * <b>修改履历：
 *
 * @author 2021-3-10 jiabingbing
 */
public class TaskCompletedListener implements FlowableEventListener {


    @Autowired
    @Lazy
    private ApprovalFlowTaskcfgService approvalFlowTaskcfgService;
    @Autowired
    @Lazy
    private RuntimeService runtimeService;
    @Autowired
    @Lazy
    private FlowableTaskService flowableTaskService;


    @Override
    public void onEvent(FlowableEvent event) {
        TaskEntity taskEntity = (TaskEntity) ((FlowableEntityEventImpl) event).getEntity();
        List<ApprovalFlowTaskcfg> taskCfgs = approvalFlowTaskcfgService.list(Wrappers.<ApprovalFlowTaskcfg>lambdaQuery()
                .eq(ApprovalFlowTaskcfg::getAftTaskId, taskEntity.getTaskDefinitionKey())
                .eq(ApprovalFlowTaskcfg::getAftProcDefId, taskEntity.getProcessDefinitionId()));
        boolean stopProcess = false;
        if (taskCfgs != null && taskCfgs.size() > 0) {
            //判断是否有多实例配置 1全员通过的话如果有一个审批不通过，则直接驳回 2单人通过的话   如果最后一个人审批不通过则执行驳回 3按比例通过的话    非正常通过则执行驳回
            ApprovalFlowTaskcfg taskCfg = taskCfgs.get(0);
            int mulType = taskCfg.getAftMulType();
            Integer mulScall = taskCfg.getAftMulScale();
            Map<String, Object> variables = runtimeService.getVariables(taskEntity.getExecutionId());
            //测试变量还没更改   所以nrOfCompletedInstances需加1   nrOfActiveInstances需减一
            Integer nrOfCompletedInstances = getInt(variables.get("nrOfCompletedInstances")) + 1;
            Integer nrOfInstances = getInt(variables.get("nrOfInstances"));
            Integer nrOfActiveInstances = getInt(variables.get("nrOfActiveInstances")) - 1;
            //全部通过
            if (mulType == FlowableConstant.TASK_MUL_TYPE_ALL) {
                //执行驳回
                if ((nrOfCompletedInstances + nrOfActiveInstances) != nrOfInstances) {
                    stopProcess = true;
                }
                //单人通过
            } else if (mulType == FlowableConstant.TASK_MUL_TYPE_SINGLE) {
                //执行完了  但是没有驳回
                if (nrOfActiveInstances == 0 && nrOfCompletedInstances == 0) {
                    stopProcess = true;
                }
                //比例通过
            } else if (mulType == FlowableConstant.TASK_MUL_TYPE_SCALE) {
                Integer full = 100;
                if (mulScall == null) {
                    mulScall = full;
                }
                if ((nrOfInstances - nrOfActiveInstances - nrOfCompletedInstances) / nrOfInstances > (full - mulScall) / full) {
                    stopProcess = true;
                }
            }
        }
        //设置抄送为待阅
        Object ccUserIds = runtimeService.getVariable(taskEntity.getProcessInstanceId(), FlowableConstant.PROCESS_VARIABLE_APPROVAL_CC_USER_IDS_ID);
        if (ObjectUtil.isNotNull(ccUserIds)) {
            String ccUserIdsStr = ccUserIds.toString();
            String[] userIds = ccUserIdsStr.split(",");
            for (String userId : userIds) {
                //2 设置抄送人为未读
                runtimeService.setVariable(taskEntity.getProcessInstanceId(), userId, FlowableConstant.PROCESS_VARIABLE_APPROVAL_CC_NO_READ);
            }
        }
        //执行驳回
        if (stopProcess) {
            TaskParam param = new TaskParam();
            param.setUserId(taskEntity.getAssignee());
            param.setTaskId(taskEntity.getId());
            param.setMessage("审核不通过，中止流程");
            flowableTaskService.stopProcessInstance(param);
        }
    }


    /**
     * 该isFailOnException()方法确定onEvent(..)方法在调度事件时抛出异常时的行为。
     * 当false返回，异常被忽略。当true返回，异常不会被忽略
     *
     * @return
     */
    @Override
    public boolean isFailOnException() {
        return true;
    }

    /**
     * 该isFireOnTransactionLifecycleEvent()方法确定此事件侦听器是在事件发生时立即触发,还是由getOnTransaction()方法确定的事务生命周期事件触发。
     * 支持的事务生命周期事件的值是：COMMITTED，ROLLED_BACK，COMMITTING，ROLLINGBACK。
     *
     * @return
     */
    @Override
    public boolean isFireOnTransactionLifecycleEvent() {
        return false;
    }

    @Override
    public String getOnTransaction() {
        return null;
    }

    private Integer getInt(Object obj) {
        if (obj == null) {
            return 0;
        } else {
            return Integer.parseInt(obj.toString());
        }
    }
}